﻿using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace Deferred.Library.Scene.Visual
{
    class SceneGraphVisual
    {
        private DeferredBase deferredBase;
        private Dictionary<DrawableObject, DrawableObjectVisual> objectVisuals = new Dictionary<DrawableObject, DrawableObjectVisual>();
        private Dictionary<Terrain, TerrainVisual> terrainVisuals = new Dictionary<Terrain, TerrainVisual>();

        public SceneGraph Scene { get; private set; }
        public CameraVisual CameraVisual { get; private set; }
        public ReadOnlyCollection<DrawableObjectVisual> ObjectVisuals { get { return new ReadOnlyCollection<DrawableObjectVisual>(new List<DrawableObjectVisual>(objectVisuals.Values)); } }
        public ReadOnlyCollection<TerrainVisual> TerrainVisuals { get { return new ReadOnlyCollection<TerrainVisual>(new List<TerrainVisual>(terrainVisuals.Values)); } }

        public SceneGraphVisual(SceneGraph scene, DeferredBase deferredBase)
        {
            this.Scene = scene;
            this.deferredBase = deferredBase;

            this.Scene.DrawableObjectAdded += new DrawableObjectAddedEvent(Scene_DrawableObjectAdded);
            this.Scene.DrawableObjectDeleted += new DrawableObjectDeletedEvent(Scene_DrawableObjectDeleted);
            this.Scene.TerrainAdded += new TerrainAddedEvent(Scene_TerrainAdded);
            this.Scene.TerrainDeleted += new TerrainDeletedEvent(Scene_TerrainDeleted);

            fillVisualLists();
        }

        private void fillVisualLists()
        {
            objectVisuals.Clear();
            terrainVisuals.Clear();

            foreach (DrawableObject o in Scene.DrawableObjects)
            {
                objectVisuals.Add(o, new DrawableObjectVisual(deferredBase, o));
            }
            foreach (Terrain t in Scene.Terrains)
            {
                terrainVisuals.Add(t, new TerrainVisual(deferredBase, t));
            }
            CameraVisual = new CameraVisual(deferredBase.DeviceService, Scene.Camera);
        }

        void Scene_TerrainDeleted(Terrain t)
        {
            terrainVisuals.Remove(t);
        }

        void Scene_TerrainAdded(Terrain t)
        {
            terrainVisuals.Add(t, new TerrainVisual(deferredBase, t));
        }

        void Scene_DrawableObjectDeleted(DrawableObject o)
        {
            objectVisuals.Remove(o);
        }

        void Scene_DrawableObjectAdded(DrawableObject o)
        {
            objectVisuals.Add(o, new DrawableObjectVisual(deferredBase, o));
        }
    }
}
